package com.meisiabc.app.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.meisiabc.app.repository.db.constant.OrderStatus;
import com.meisiabc.app.repository.db.entity.Lesson;
import com.meisiabc.app.repository.db.entity.PurchaseCourse;
import com.meisiabc.app.repository.db.entity.Student;
import com.meisiabc.app.repository.db.manager.LessonManager;
import com.meisiabc.app.repository.db.manager.PurchaseCourseManager;
import com.meisiabc.app.repository.db.manager.StudentManager;
import com.meisiabc.support.wechat.WechatPay;
import com.meisiabc.utils.UUIDUtils;
import com.meisiabc.utils.Verify;
import com.meisiabc.utils.math.BigDecimalUtils;
import com.riversoft.weixin.common.util.XmlObjectMapper;
import com.riversoft.weixin.pay.payment.bean.PaymentNotification;
import com.riversoft.weixin.pay.payment.bean.Signature;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class OrderService {
    @Autowired
    private StudentManager studentManager;
    @Autowired
    private PurchaseCourseManager purchaseCourseManager;
    @Autowired
    private WechatPay wechatPay;
    @Autowired
    private LessonManager lessonManager;

    public List<JSONObject> getOrderList(String mobile, Integer isPay) {
        Student student = studentManager.selectByMobile(mobile);
        if (student == null) {
            return null;
        }

        String isPayDesc = null;
        if (isPay != null) {
            OrderStatus orderStatus = OrderStatus.valueOf(isPay);
            if (orderStatus != null) {
                isPayDesc = orderStatus.getDesc();
            }
        }

        List<JSONObject> result = new ArrayList<>();
        List<PurchaseCourse> courses = null;
        if (isPayDesc == null) {
            courses = purchaseCourseManager.selectByStudentId(student.getStudentId());
        } else {
            courses = purchaseCourseManager.selectByStudentId(student.getStudentId(), isPayDesc);
        }

        if (courses == null || courses.isEmpty()) {
            return result;
        }


        for (PurchaseCourse course : courses) {
            Lesson lesson = lessonManager.getById(course.getMaterial());
            String title = "";
            if (lesson != null) {
                title = lesson.getNameEn();
            }
            int total_hour = course.getHoursEnrolled() == null ? 0 : course.getHoursEnrolled();
            result.add(new JSONObject()
                    .fluentPut("id", course.getId())
                    .fluentPut("uniqueid", course.getUniqueid())
                    .fluentPut("title", title)
                    .fluentPut("total_hour", total_hour / 60.0)
                    .fluentPut("purchase_time", course.getPurchaseDate())
                    .fluentPut("money", course.getMoney())
                    .fluentPut("is_pay", course.getIsPay())

            );
        }

        return result;
    }

    public JSONObject prepay(String mobile, String openid, Integer material, Integer hoursEnrolled, BigDecimal money, DateTime now) {
        Verify.isTrue(BigDecimalUtils.is(money).gt(BigDecimal.ZERO), "请输入正确的金额");

        Student student = studentManager.selectByMobile(mobile);
        Verify.notNull(student, "学生不存在");

        String orderId = UUIDUtils.getUUID();
        purchaseCourseManager.save(PurchaseCourse.builder()
                .uniqueid(orderId).
                        studentId(student.getStudentId()).
                        material(String.valueOf(material)).
                        hoursEnrolled(hoursEnrolled).
                        hoursRemaining(hoursEnrolled).
                        lessonsCompleted(0).
                        purchaseDate(now.toString("yyyy-MM-dd")).
                        isDelete(0).
                        payMethod("微信付款").
                        type("新报课程").
                        money(money).
                        isPay(OrderStatus.to_pay.getDesc())
                .build());

        String prepayId = wechatPay.prepay(openid, "美思英语充值中心-课程购买充值", orderId, money.intValue() * 100);
        Verify.isTrue(!StringUtils.isBlank(prepayId), "暂时无法充值");

        Signature signature = wechatPay.createJsSignature(prepayId);
        Verify.notNull(signature, "暂时无法充值");

        return new JSONObject().fluentPut("appId", signature.getAppId())
                .fluentPut("timeStamp", signature.getTimestamp())
                .fluentPut("nonceStr", signature.getNonce())
                .fluentPut("package", signature.getPack())
                .fluentPut("signType", "MD5")
                .fluentPut("paySign", signature.getSignature());
    }

    public void payCallback(String body) {
        if (StringUtils.isBlank(body)) {
            return;
        }

        try {
            PaymentNotification notification = XmlObjectMapper.defaultMapper().fromXml(body, PaymentNotification.class);
            log.info("Payment Notification: {}", JSON.toJSONString(notification));
            if (notification != null && wechatPay.checkSignature(notification) && notification.success()) {
                String orderId = notification.getTradeNumber();
                purchaseCourseManager.updateByUniqueidSelective(orderId, OrderStatus.payed);
            }
        } catch (Exception e) {
            log.error("PaymentNotification mapper error.[xml={}]", body);
        }
    }

    public String payCallbackSuccess() {
        return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
    }
}
